package MusicModel;
import javax.sound.midi.*;

import Beat.BPMObserver;
import Beat.BeatModelInterface;
import Beat.BeatObserver;

import java.util.*;
//import polymorphism.music.Note;

public class MusicModel implements BeatModelInterface {
    
	ArrayList beatObservers = new ArrayList();
	ArrayList bpmObservers = new ArrayList();
    int bpm = 90;
    private int tipoDeVista=1;
    /* Defimos: 1- DJView
     * 			2- MusicMixPad
     * */
    
    //MusicDrive 4- Creacion de instrumentos
    private Secuencia platillo, bombo, redoblante;
    private int instrumentoActual;
    /*Definimos: instrumentoActual= 1 --> platillo
     * 			 instrumentoActual= 2 --> bombo
     * 			 instrumentoActual= 3 --> redoblante
     */
    
    public MusicModel(){
    	
    	instrumentoActual =1;
        platillo = new Instrumento( "Platillo" , 46 , 1 , beatObservers);
        bombo = new Instrumento( "Bombo" , 35 , 2 , beatObservers);
        redoblante = new Instrumento( "Redoblante" , 40 , 3 , beatObservers); //38 y 40
        initialize();
        notifyBPMObservers();
        
    }
    
	public void initialize() {
		
		platillo.crear();
        bombo.crear();
        redoblante.crear();
       
	}
 
	//MusicDrive: 5- Creamos hilos que reproduzcan los sonidos independientemente
    public void on() {
        
        platillo.iniciar();
        bombo.iniciar();
        redoblante.iniciar();
        
    }
    
    //MusicDrive: 6- Parar sonidos
    public void off() {
		
		platillo.parar();
		bombo.parar();
		redoblante.parar();
		
    }
 
    //MusicDrive 3- Setear el BPM del instrumento actual
    public void setBPM(int valor) {
    	
		bpm = valor;
		
		if(instrumentoActual==1){
        	platillo.setBpm(valor);
        	notifyBPMObservers();
        }else
        if(instrumentoActual==2){
        	bombo.setBpm(valor);
        	notifyBPMObservers();
        }else
        if(instrumentoActual==3){
        	redoblante.setBpm(valor);
        	notifyBPMObservers();
        }
		
    }
  
	public int getBPM() {
		
		if(instrumentoActual==1){
        	//System.out.println("Cambiando a 2. instrumentoActual="+instrumentoActual);
        	return platillo.getBpm();
        	//System.out.println("Cambiado a 2. instrumentoActual="+instrumentoActual);
        }else
        if(instrumentoActual==2){
        	return bombo.getBpm();
        }else
        if(instrumentoActual==3){
        	return redoblante.getBpm();
        }
		//reiniciar();
		return bpm;
	}
	
	public void reiniciar(){
		off();
		on();
	}
	
    //MusicDrive: 1- Pasar al instrumento siguiente
	public void sgteInstrumento(){
		
        if(instrumentoActual==1){
        	//System.out.println("Cambiando a 2. instrumentoActual="+instrumentoActual);
        	instrumentoActual=2;
        	notifyBPMObservers();
        	System.out.println("Instrumento actual bombo");
        }else
        if(instrumentoActual==2){
        	instrumentoActual=3;
        	notifyBPMObservers();
        	System.out.println("Instrumento actual redoblante");
        }else
        if(instrumentoActual==3){
        	instrumentoActual=1;
        	notifyBPMObservers();
        	System.out.println("Instrumento actual platillo");
        }
        //Actualizar texto y bpm general
        //Cambiar de color la beatbar
	}
	
    //MusicDrive: 2- Pasar al instrumento anterior
	public void anteInstrumento(){
		if(instrumentoActual==1){
			instrumentoActual=3;
			notifyBPMObservers();
			System.out.println("Instrumento actual redoblante");
        }else
        if(instrumentoActual==2){
        	instrumentoActual=1;
        	notifyBPMObservers();
        	System.out.println("Instrumento actual platillo");
        }else
        if(instrumentoActual==3){
        	instrumentoActual=2;
        	notifyBPMObservers();
        	System.out.println("Instrumento actual bombo");
        }
        //Actualizar texto y bpm general
        //Cambiar de color la beatbar
	}
	
	public int getInstrumentoActual(){
		return instrumentoActual;
	}
  
	public void setVista(int valor){
		tipoDeVista= valor;
	}
	
	public int getVista(){
		return tipoDeVista;
	}
	
	void beatEvent() {
		notifyBeatObservers();
	}
  
   
	public void registerObserver(BeatObserver o) {
		System.out.println("Se inscribio un nuevo Observador de Beats");
		beatObservers.add(o);
	}
  
	public void notifyBeatObservers() {
		for(int i = 0; i < beatObservers.size(); i++) {
			System.out.println("Avise a todos los observadores de los Beats");
			BeatObserver observer = (BeatObserver)beatObservers.get(i);
			observer.updateBeat();
		}
	}
  
	public void registerObserver(BPMObserver o) {
		System.out.println("Se inscribio un nuevo Observador de BPM");
		bpmObservers.add(o);
	}
  
	public void notifyBPMObservers() {
		for(int i = 0; i < bpmObservers.size(); i++) {
			System.out.println("Avise a todos los observadores de los BPM");
			BPMObserver observer = (BPMObserver)bpmObservers.get(i);
			observer.updateBPM();
		}
	}


	public void removeObserver(BeatObserver o) {
		int i = beatObservers.indexOf(o);
		if (i >= 0) {
			beatObservers.remove(i);
		}
	}

	public void removeObserver(BPMObserver o) {
		int i = bpmObservers.indexOf(o);
		if (i >= 0) {
			bpmObservers.remove(i);
		}
	}

}
